/*
 * Server.cpp
 *
 *  Created on: Aug 11, 2012
 *      Author: nam20485
 */

#include "IServer.h"
#include "Logger.h"

IServer::IServer(/*ServerReceiveHandler m_pfnReceiveHandler*/)
	: m_ulConnectionCount(0)
	//, m_pfnReceiveHandler(m_pfnReceiveHandler)
{
	memset(m_apConnections, 0, sizeof(Connection*)*MAX_CONNECTIONS);
}

IServer::~IServer()
{
	for (unsigned long l = 0; l < MAX_CONNECTIONS; l++)
	{
		if (m_apConnections[l])
		{
			delete m_apConnections[l];
			m_apConnections[l] = 0;
		}
	}
}

Connection::ID IServer::Connect(/*const*/ IConnector& connector)
{
	Logger::log("IServer::Connect() - enter]\n\r");

	if (m_ulConnectionCount < MAX_CONNECTIONS)
	{
		Connection::ID lNewID = static_cast<Connection::ID>(m_ulConnectionCount);
		Connection * pConnection = new Connection(	lNewID,
													connector/*,
													reinterpret_cast<Connection::ConnectionReceiveHandler>( &Server::OnConnectionReceive)*/);

		if (pConnection->Connect() == Connection::SUCCESS)
		{
			m_apConnections[m_ulConnectionCount++] = pConnection;

			Logger::log("IServer::Connect() - connected]\n\r");

			return lNewID;
		}
		else
		{
			Logger::log("IServer::Connect() - connection FAILED]\n\r");
		}
	}

	Logger::log("IServer::Connect() - connect failed]\n\r");
	Logger::log("IServer::Connect() - exit]\n\r");

	return -1;
}

IServer::RESPONSE IServer::Shutdown()
{
	RESPONSE response = SUCCESS;
	// disconnect all connections
	for (unsigned long i = 0; i < m_ulConnectionCount; i++)
	{
		if (m_apConnections[i] != 0)
		{
			if (m_apConnections[i]->Disconnect() == Connection::FAIL)
			{
				response = FAIL;
			}
		}
	}
	return response;
}

IServer::RESPONSE IServer::Send(const Message& message, Connection::ID connectionID /* = 0*/)
{
	const Connection* kpConnection = FindConnection(connectionID);
	if (kpConnection != 0)
	{
		if (kpConnection->Send(message) == Connection::SUCCESS)
		{
			return SUCCESS;
		}
	}
	return FAIL;
}

const Message* IServer::Receive(Connection::ID connectionID /* = 0*/)
{
	Logger::log("[Server::Receive(");
	Logger::log(connectionID);
	Logger::log(") - enter]\n\r");

	const Connection* kpConnection = FindConnection(connectionID);
	if (kpConnection != 0)
	{
		Logger::log("[Server::Receive(");
		Logger::log(connectionID);
		Logger::log(") - found]\n\r");

		return kpConnection->Receive();
	}
	else
	{
		Logger::log("[Server::Receive(");
		Logger::log(connectionID);
		Logger::log(") - NOT found]\n\r");
	}

	return 0;	// NULL
}

IServer::RESPONSE IServer::Serve(Connection::ID id /* = 0*/)
{
	RESPONSE response = FAIL;

	Logger::log("[Server::Serve(");
	Logger::log(id);
	Logger::log(") - enter]\n\r");

	const Message* pReceived = Receive(id);
	if (pReceived != 0)
	{
		Logger::log("[Server::Serve(");
		Logger::log(id);
		Logger::log(") - message received]\n\r");

		response = HandleMessage( *pReceived, id);

		delete pReceived;
		pReceived = 0;
	}
	else
	{
		Logger::log("[Server::Serve(");
		Logger::log(id);
		Logger::log(") - message NoT received]\n\r");
		response = RECEIVE_FAILED;
	}

	Logger::log("[Server::Serve(");
	Logger::log(id);
	Logger::log(") - exit]\n\r");

	return response;
}

IServer::RESPONSE IServer::Loop(Connection::ID id)
{
	RESPONSE response = FAIL;
	while (true)
	{
		response = Serve(id);
		if (response != SUCCESS)
		{
			break;
		}
	}

	return response;
}

//void Server::OnConnectionReceive(Connection::ID lClientID, const Message& message)
//{
//	if (m_pfnReceiveHandler)
//	{
//		m_pfnReceiveHandler(lClientID, message);
//	}
//}

inline const Connection* IServer::FindConnection(Connection::ID id) const
{
	Logger::log("[Server::FindConnection(");
	Logger::log(id);
	Logger::log(") - enter]\n\r");

	for (unsigned long ul = 0; ul < m_ulConnectionCount; ul++)
	{
		if (m_apConnections[ul] != 0)
		{
			if (m_apConnections[ul]->getID() == id)
			{
				Logger::log("[Server::FindConnection(");
				Logger::log(id);
				Logger::log(") - FOUND]\n\r");

				return m_apConnections[ul];
			}
		}
	}

	Logger::log("[Server::FindConnection(");
	Logger::log(id);
	Logger::log(") - NOT found]\n\r");

	return 0;
}
